package de.g18.llmaa.gui.workspace;

import de.g18.llmaa.gui.App_Model_Database;
import de.g18.llmaa.gui.IApp_Model;
import de.g18.llmaa.gui.workspace.internalFrame.Abstract_InternalFrame;
import de.g18.llmaa.gui.workspace.internalFrame.product.InternalFrame_Product;
import de.g18.llmaa.logic.vos.VOKey;
import de.g18.llmaa.logic.vos.VOProduct_Key;

/**
 * Der Workspace Controler kümmert sich um das Anzeigen der einzelnen Fenster.
 * 
 * @author Gruppe LLMAA
 * 
 */
public class Workspace_Crtl {

	private static Workspace_Crtl instnace = null;
	private IWorkspace_Model model;

	/**
	 * Instnaziiert den Workspace Controler
	 * 
	 * Diese Klasse darf nur duch den aufruf der Methode getInstanze
	 * Instanziiert werden, um einzigartig zu sein.
	 * 
	 * Das Workspace Model wird Instanziiert.
	 */
	private Workspace_Crtl() {
		model = new Workspace_Model();
	}

	/**
	 * Static Zugriff duch die Instanzieierung eines Singleton Objektes.
	 * 
	 * @return
	 */
	public static Workspace_Crtl getInstnace() {
		if (instnace == null)
			instnace = new Workspace_Crtl();
		return instnace;
	}

	public IWorkspace_Model getModel() {
		return model;
	}

	/**
	 * Hinzufügen eines Sichtbaren objektes auf dem Workspace ... sollte es ein
	 * Objekt mit beziehungen zu einen Obergeordneten Objekt beispie Serial zu
	 * Produkt so werden die Obergeordnetten Objekte ebenfalls erstellt.
	 * 
	 * @param visibleObject
	 */
	public void addVisibleComponent(Object visibleObject) {

		// Prüfen ob das Anzuzeigende Elemenet bereits ein Fenster ist
		if (visibleObject instanceof Abstract_InternalFrame) {
			addInternalFrame((Abstract_InternalFrame) visibleObject);
			// Sollte es ein Produkt sein
		} else if (visibleObject instanceof VOProduct_Key) {
			addInternalFrame(new InternalFrame_Product(
					(VOProduct_Key) visibleObject));
			// Sollte es ein Schlüssel sein.
		} else if (visibleObject instanceof VOKey) {
			try {
				/*
				 * Ist das dazugehöriege Produkt Element schon vorhanden wird
				 * der Schlüssel auf diesem Erstellt.
				 */
				InternalFrame_Product internalFrame = getInternalProductFrame(((VOKey) visibleObject)
						.getKey_Product());

				internalFrame.addVisibleComponent((VOKey) visibleObject);
			} catch (Exception e) {
				/*
				 * Wurde noch kein Produkt Fenster auf dem Desktop gefunden so
				 * wird eins erstellt und die Methode erneut ausgeführt beim
				 * zweiten ausführen ist ein Fenster vorhanden.
				 */
				addVisibleComponent(((VOKey) visibleObject).getKey_Product());
				addVisibleComponent(visibleObject);
			}

		}
	}

	/**
	 * Hinzufügen eines neuen Fenstern zum Model. Es wird geprüft ob das Fenster
	 * schon auf dem Workspace vorhanden ist.
	 * 
	 * @param internalFrame
	 */
	private void addInternalFrame(Abstract_InternalFrame internalFrame) {
		if (checkNotInList(internalFrame)) {
			model.addInternalFrame(internalFrame);

		}

	}

	/**
	 * Pürfung ob bereits ein Fenster mit gleichem Titel nicht Vorhanden ist.
	 * 
	 * @param internalFrame
	 *            neues Fenster
	 * @return false = Fenster ist in der Liste vorhanden <br>
	 *         true = Fenster ist nicht in der Liste.
	 */
	private boolean checkNotInList(Abstract_InternalFrame internalFrame) {
		for (Abstract_InternalFrame visibleFrame : model
				.getList_VisibleFrames()) {
			if (visibleFrame.getTitle() == internalFrame.getTitle())
				return false;
		}
		return true;
	}

	/**
	 * Raussuchen eines Bestimmten Produkt Anzeige Elemententes.
	 * 
	 * @param poduct
	 *            {@link VOProduct_Key} das Produkt für welches das
	 *            AnzeigeElement Gesucht wird.
	 * 
	 * @return wenn es ein Anzeige Element giebt wird dieses zurrückgegeben,
	 *         sollte keins vorhanden sein giebt die Methode null zurück.
	 */
	public InternalFrame_Product getInternalProductFrame(VOProduct_Key poduct) {
		for (Abstract_InternalFrame internalFrame : model
				.getList_VisibleFrames()) {
			if (internalFrame instanceof InternalFrame_Product) {
				if (internalFrame.getTitle() == poduct.getProduct_Name()) {
					return (InternalFrame_Product) internalFrame;
				}
			}
		}
		return null;

	}

	/**
	 * Entfernen eines Fensters vom Workspace
	 * 
	 * @param internalFrame
	 *            Das Fenster Welches entfernt werden soll.
	 */
	public void removeVisibleComponent(Abstract_InternalFrame internalFrame) {
		model.removeInternalFrame(internalFrame);

	}


}
